﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO.IsolatedStorage;
using System.IO;
using System.Text;
using Microsoft.Phone.Info;
using Store.WP7.Framework;
using System.Globalization;
using Microsoft.Phone.Tasks;
using Store.WP7.Framework.Helpers;
using Coding4Fun.Phone.Controls.Data;

namespace Store.WP7.Framework
{
    ///<summary>
    /// ExceptionManager
    /// Used to send an automatic and anonymous error report
    /// </summary>
    public class ExceptionManager
    {
        #region Properties

        private const string filename = "BugReport";

        #endregion

        #region Singleton

        private static readonly ExceptionManager instance = new ExceptionManager();
        ///<summary>
        /// Gets ExceptionManager instance
        /// </summary>
        public static ExceptionManager Instance
        {
            get
            {
                return ExceptionManager.instance;
            }
        }

        ///<summary>
        /// Initializes static members of the ExceptionManager class
        /// </summary>
        static ExceptionManager()
        {
        }

        ///<summary>
        /// Prevents a default instance of the ExceptionManager class from being created
        /// </summary>
        private ExceptionManager()
        {
        }

        #endregion

        #region Public Methods

        ///<summary>
        /// Report exception
        /// </summary>
        /// <param name="ex">The exception to report</param>
        public void SaveException(Exception ex)
        {
            if (ex == null)
                return;

            try
            {
                long deviceTotalMemory = DeviceStatus.DeviceTotalMemory / 1024 / 1024;
                long applicationCurrentMemoryUsage = DeviceStatus.ApplicationCurrentMemoryUsage / 1024 / 1024;
                long applicationPeakMemoryUsage = DeviceStatus.ApplicationPeakMemoryUsage / 1024 / 1024;

                var exContainer = new ExceptionStorage()
                {
                    AppVersion = PhoneHelper.GetAppAttribute("Version"),
                    Message = ex.Message,
                    StackTrace = ex.StackTrace,
                    DeviceFirmwareVersion = DeviceStatus.DeviceFirmwareVersion,
                    DeviceName = string.Format("{0} {1}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceName),
                    OSVersion = Environment.OSVersion.Version.ToString(),
                    Locale = CultureInfo.CurrentCulture.EnglishName,
                    TotalMemory = deviceTotalMemory.ToString("N2"),
                    CurrentMemory = applicationCurrentMemoryUsage.ToString("N2"),
                    PeakMemory = applicationPeakMemoryUsage.ToString("N2")
                };

                object deviceUniqueID;
                if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out deviceUniqueID))
                {
                    var deviceIDbyte = (byte[])deviceUniqueID;
                    string deviceID = Convert.ToBase64String(deviceIDbyte);

                    exContainer.DeviceUniqueId = deviceID;
                }

                CacheManager.Current.Add(filename, exContainer);
            }
            catch (Exception exception)
            {
            }
        }

        ///<summary>
        /// Check for previous logged exception
        /// </summary>
        /// <returns>Return the exception if found</returns>
        public ExceptionStorage GetPreviousException(bool deleteSavedReport)
        {
            ExceptionStorage exceptionData = null;

            try
            {
                exceptionData = CacheManager.Current.Get<ExceptionStorage>(filename);
            }
            catch (Exception ex) { /* Nothing here, just making it safe */ }
            finally
            {
                if (deleteSavedReport)
                    SafeDeleteFile();
            }

            if (exceptionData != null)
                return exceptionData;

            return null;
        }

        private static void SafeDeleteFile()
        {
            try
            {
                CacheManager.Current.Remove(filename);
            }
            catch { /* Nothing here, just making it safe */ }
        }

        public string GetReport(ExceptionStorage exception)
        {
            var report = new StringBuilder();

            report.AppendFormat("App version : {0}", exception.AppVersion);
            report.AppendLine();
            report.AppendFormat("Model : {0}", exception.DeviceName);
            report.AppendLine();
            report.AppendFormat("DeviceFirmwareVersion : {0}", exception.DeviceFirmwareVersion);
            report.AppendLine();
            report.AppendFormat("DeviceUniqueId : {0}", exception.DeviceUniqueId);
            report.AppendLine();
            report.AppendFormat("Locale : {0}", exception.Locale);
            report.AppendLine();
            report.AppendFormat("CurrentMemory : {0}", exception.CurrentMemory);
            report.AppendLine();
            report.AppendFormat("TotalMemory : {0}", exception.TotalMemory);
            report.AppendLine();
            report.AppendFormat("PeakMemory : {0}", exception.PeakMemory);
            report.AppendLine();
            report.AppendLine("----------------------------------------------");
            report.AppendLine(exception.Message);
            report.AppendLine(exception.StackTrace);

            return report.ToString();
        }

        #endregion
    }
}

